<!--
 * @PageName: @拖拽上传组件
 * @Description: 
 * @FilePath: /glm-mes-pc/src/components/DragUploadFile/index.vue
-->
<template>
	<el-upload
		drag
		:headers="headers"
		:action="uploadUrl"
		:show-file-list="false"
		:before-upload="handleBeforeUpload"
		:on-success="handleUploadSuccess"
		:on-error="handleUploadError"
		ref="uploadRef"
		:limit="limitCount"
		:on-exceed="handleExceed"
		v-hasPermi="['file:dept:upload']"
	>
		<div>
			<el-icon class="el-icon--upload"><upload-filled /></el-icon>
			<div>
				<span>请将{{ upperCaseLimitType.join('、') }}文件拖入该区域内或</span>
				<span>&nbsp;点击上传</span>
			</div>
		</div>
	</el-upload>

	<div v-if="uploadNum > 0 || alreadyUploadNum > 0" class="file-list">
		<div v-for="item in alreadyUploadFlag ? alreadyUploadFileList : uploadFileList" :key="item.url" class="file-item">
			<div class="left">
				<svg-icon v-if="item.name.includes('.pdf')" icon-class="pdf2" />
				<svg-icon v-if="item.name.includes('.jpg') || item.name.includes('.jpeg') || item.name.includes('.png')" icon-class="tupian2" />
				<svg-icon v-if="item.name.includes('.ai')" icon-class="ai" />
			</div>
			<div class="right">
				<div class="file-detail">
					<div class="file-name">{{ item.name }}</div>
					<div v-if="item.uploadByName && item.uploadTime" class="creator-time mt4">
						<div class="creator mr10">
							<span class="mr5">创建人:</span>
							<span>{{ item.uploadByName }}</span>
						</div>
						<div class="time">
							<span class="mr5">创建时间:</span>
							<span>{{ item.uploadTime }}</span>
						</div>
					</div>
				</div>
				<div class="btn">
					<span @click="handlePreview(item)" v-if="!item.name.includes('.ai')">预览</span>
					<span @click="handleDownload(item)">下载</span>
					<span @click="handleDelete(item)" v-hasPermi="['file:dept:upload']">删除</span>
				</div>
			</div>
		</div>
	</div>

	<!-- pdf文件预览弹框 -->
	<FileDetailDialog v-model:isShow="fileDetailDialogVisble" :fileUrl="fileUrl" :title="fileName" />
</template>

<script setup>
import { getToken } from '@/utils/auth'
import { commDownloadFile, downloadFileWithCustomName } from '@/utils/index.js'
import FileDetailDialog from '@/views/Dialog/FileDetailDialog'
import { deleteOrderDataAPI } from '@/api/order'
const { proxy } = getCurrentInstance()
let props = defineProps({
	modelValue: [String, Object, Array],
	limitType: {
		type: Array,
		default: () => []
	},
	fileSizeLimit: {
		type: Number,
		default: 0
	},
	limitCount: {
		type: Number,
		default: null
	},
	alreadyUploadFlag: {
		type: Boolean,
		default: false
	},
	alreadyUploadFileList: {
		type: Array,
		default: () => []
	}
})
let { limitType, fileSizeLimit, alreadyUploadFlag, alreadyUploadFileList } = toRefs(props)
const emit = defineEmits()

// 上传请求头
const headers = ref({ Authorization: 'Bearer ' + getToken() })
// 上传服务器地址
const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + '/system/oss/upload')
// 上传文件列表
const uploadFileList = ref([])
// 暂存文件
const stagingFileList = ref([])

const upperCaseLimitType = computed(() => {
	return limitType.value.map((item) => item.toUpperCase())
})
// 上传的文件数量
const uploadNum = computed(() => uploadFileList.value.length)
// 已上传-接口返回的上传的文件数量
const alreadyUploadNum = computed(() => alreadyUploadFileList.value.length)
const number = ref(0)

watch(
	() => props.modelValue,
	(val) => {
		if (val && Object.keys(val).length) {
			let temp = 1
			// 首先将值转为数组
			const list = Array.isArray(val) ? val : props.modelValue.split(',')
			// 然后将数组转为对象数组
			uploadFileList.value = list.map((item) => {
				if (typeof item === 'string') {
					item = { name: item, url: item }
				}
				item.uid = item.uid || new Date().getTime() + temp++
				return item
			})
		} else {
			uploadFileList.value = []
			return []
		}
	},
	{ deep: true, immediate: true }
)

// 文件个数超出
function handleExceed() {
	proxy.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`)
}

/* 上传之前校验文件 */
const handleBeforeUpload = (file) => {
	// 检验文件类型
	const fileType = file.name.slice(file.name.lastIndexOf('.') + 1)
	const isTypeOk = limitType.value.some((type) => {
		if (type == fileType) return true
	})
	if (!isTypeOk) {
		proxy.$modal.msgError(`文件格式不正确, 请上传${upperCaseLimitType.value.join('、')}格式文件！`)
		return false
	}

	// 校检文件大小
	if (fileSizeLimit.value) {
		const isLt = file.size / 1024 / 1024 < fileSizeLimit.value
		if (!isLt) {
			proxy.$modal.msgError(`上传文件大小不能超过${fileSizeLimit.value}MB!`)
			return false
		}
	}

	proxy.$modal.loading('正在上传文件，请稍候...')
	number.value++
	return true
}
/* 上传成功 */
const handleUploadSuccess = ({ code, data }, file) => {
	if (code === 200) {
		// 待上传-首次上传
		if (!alreadyUploadFlag.value) {
			stagingFileList.value.push({ name: data.fileName, url: data.url })
			uploadedSuccessfully()
		} else {
			// 已上传-重新上传
			stagingFileList.value.push({ name: data.fileName, url: data.url })
			uploadedSuccessfully()
			// 已上传列表
			alreadyUploadFileList.value.push({ name: data.fileName, url: data.url })
		}
	} else {
		number.value--
		proxy.$modal.closeLoading()
		proxy.$modal.msgError('上传失败')
		proxy.$refs.uploadRef.handleRemove(file)
		uploadedSuccessfully()
	}
}

// 上传结束处理
const uploadedSuccessfully = () => {
	if (number.value > 0 && stagingFileList.value.length === number.value) {
		uploadFileList.value = uploadFileList.value.filter((f) => f.url !== undefined).concat(stagingFileList.value)
		stagingFileList.value = []
		number.value = 0
		emit('update:modelValue', uploadFileList.value)
		proxy.$modal.closeLoading()
	}
}

// 对象转成指定字符串分隔
const listToString = (list, separator) => {
	let strs = ''
	separator = separator || ','
	for (let i in list) {
		if (list[i].url) {
			strs += list[i].url + separator
		}
	}
	return strs != '' ? strs.substring(0, strs.length - 1) : ''
}

/* 上传失败 */
const handleUploadError = () => {
	proxy.$modal.closeLoading()
	proxy.$modal.msgError('上传文件失败')
}

/* 删除 */
const handleDelete = (row) => {
	if (!alreadyUploadFlag.value) {
		// 待上传-删除已上传的文件
		uploadFileList.value.forEach((file, index) => {
			if (file.url == row.url) {
				uploadFileList.value.splice(index, 1)
				emit('update:modelValue', uploadFileList.value)
			}
		})
	} else {
		// 已上传-删除已上传的文件(1.调用接口删除; 2.删除重新上传的文件)
		proxy.$modal
			.confirm(`确定删除 ${row.name} ?`)
			.then(async () => {
				/* 调用接口删除已上传的文件(存在id) */
				if (row.id) {
					await deleteOrderDataAPI({ id: row.id })
					alreadyUploadFileList.value.forEach((item, index) => {
						if (item.id == row.id) {
							alreadyUploadFileList.value.splice(index, 1)
						}
					})
				} else {
					/* 手动删除重新上传的文件 */
					// 1.删除重新上传列表中的数据
					uploadFileList.value.forEach((item, index) => {
						if (item.url == row.url) {
							uploadFileList.value.splice(index, 1)
							emit('update:modelValue', uploadFileList.value)
						}
					})
					// 2.更新已上传列表中的数据
					alreadyUploadFileList.value.forEach((item, index) => {
						if (item.url == row.url) {
							alreadyUploadFileList.value.splice(index, 1)
						}
					})
				}
			})
			.catch(() => {})
	}
}

const fileDetailDialogVisble = ref(false)
const fileUrl = ref('')
const fileName = ref('')
// 预览已上传的工艺资料
const handlePreview = (row) => {
	fileDetailDialogVisble.value = true
	fileUrl.value = row.url
	fileName.value = row.name
}

// 下载已上传的工艺资料
const handleDownload = (row) => {
	// commDownloadFile(row.url)
	// window.open(row.url)
	downloadFileWithCustomName(row.url, row.name)
}
</script>

<style lang="scss" scoped>
// 已上传的文件列表
.file-list {
	margin: 10px 0;
	font-size: 12px;
	color: #061326;
	max-height: 300px;
	overflow-y: auto;
	// 已上传的每一项文件
	.file-item {
		display: flex;
		align-items: center;
		justify-content: space-between;
		margin-bottom: 10px;
		padding: 10px;

		&:hover {
			background-color: #f5f7fa;
		}
	}
	.file-item .left .svg-icon {
		font-size: 30px;
		margin-right: 10px;
	}
	.file-item .right {
		flex: 1;
		display: flex;
		align-items: center;
		justify-content: space-between;
	}
	.right .file-detail {
		display: flex;
		flex-direction: column;
	}
	.file-detail .file-name {
		font-size: 14px;
		width: 200px;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}
	.file-detail .creator-time {
		display: flex;
		font-size: 12px;
	}
	.right .btn {
		color: #265bae;
		span {
			margin-right: 20px;
			cursor: pointer;
			&:hover {
				color: #409eff;
			}
			&:last-child {
				margin-right: 5px;
				&:hover {
					color: #be1c1c;
				}
			}
		}
	}
}
</style>
